//download.js v4.2, by dandavis; 2008-2016. [MIT] see http://danml.com/download.html for tests/usage
// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.
// v4 adds AMD/UMD, commonJS, and plain browser support
// v4.1 adds url download capability via solo URL argument (same domain/CORS only)
// v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors
// https://github.com/rndme/download
import Id3 from 'browser-id3-writer';

export default function download(data, strFileName, strMimeType = null, songInfo = null, cb = {}) {
  var self = window, // this script is only for browsers anyway...
    defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads
    mimeType = strMimeType || defaultMime,
    payload = data,
    url = data,
    anchor = document.createElement("a"),
    toString = function(a){return String(a);},
    myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString),
    fileName = strFileName || "download",
    blob,
    reader,
  myBlob= myBlob.call ? myBlob.bind(self) : Blob ;

  if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
    payload=[payload, mimeType];
    mimeType=payload[0];
    payload=payload[1];
  }


  if(url && url.length< 2048){ // if no filename and no mime, assume a url was passed as the only argument

    anchor.href = url; // assign href prop to temp anchor
    if(anchor.href.indexOf(url) !== -1){ // if the browser determines that it's a potentially valid url path:
      var ajax=new XMLHttpRequest();
      ajax.open( "GET", url, true);
      ajax.responseType = 'arraybuffer';
      ajax.onload= function(e){
        if (e.currentTarget.status === 200) {
          var downInfo = e.target.response;
          // 下面是下载歌曲图片，通过 id3 加到歌曲信息中，这样就能显示图片了
          if (songInfo && songInfo.al && songInfo.al.picUrl) {
            var coverAjax = new XMLHttpRequest();
            coverAjax.open('GET', songInfo.al.picUrl.replace(/http(s|):\/\/y\.gtimg\.cn/, `http://${window.location.host}/qqImg`), true);
            coverAjax.responseType = 'arraybuffer';
            coverAjax.onload = function (cE) {
              try {
                if (cE.currentTarget.status === 200) {
                  const writer = new Id3(e.target.response);
                  writer.setFrame('TIT2', songInfo.name)
                    .setFrame('APIC', {
                      type: 3,
                      data: coverAjax.response,
                      description: songInfo.al.name,
                    });
                  writer.addTag();
                  downInfo = writer.arrayBuffer;
                }
              } catch (err) {
                console.log('DOWN ERR: ', err);
              }
              setTimeout(() => {
                cb.success && cb.success();
                download(downInfo, fileName, defaultMime);
              }, 10);
            };

            coverAjax.send();
          } else {
            cb.success && cb.success();
            download(downInfo, fileName, defaultMime);
          }
        }
        cb.error && cb.error();
      };
      // 下载进度
      ajax.addEventListener('progress', function (e) {
        if (e.lengthComputable) {
          var percentComplete = e.loaded / e.total;
          cb.progress && cb.progress(percentComplete, e.loaded, e.total);
        }
      });
      setTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return:
      // 创建之后的回调，这个ajax可以方便用来取消等。
      cb.init && cb.init(ajax);
      return ajax;
    } // end if valid url?
  } // end if url?


  //go ahead and download dataURLs right away
  if(/^data:([\w+-]+\/[\w+.-]+)?[,;]/.test(payload)){

    if(payload.length > (1024*1024*1.999) && myBlob !== toString ){
      payload=dataUrlToBlob(payload);
      mimeType=payload.type || defaultMime;
    }else{
      return navigator.msSaveBlob ?  // IE10 can't do a[download], only Blobs:
        navigator.msSaveBlob(dataUrlToBlob(payload), fileName) :
        saver(payload) ; // everyone else can save dataURLs un-processed
    }

  }else{//not data url, is it a string with special needs?
    if(/([\x80-\xff])/.test(payload)){
      var i=0, tempUiArr= new Uint8Array(payload.length), mx=tempUiArr.length;
      for(i;i<mx;++i) tempUiArr[i]= payload.charCodeAt(i);
      payload=new myBlob([tempUiArr], {type: mimeType});
    }
  }
  blob = payload instanceof myBlob ?
    payload :
    new myBlob([payload], {type: mimeType}) ;


  function dataUrlToBlob(strUrl) {
    var parts= strUrl.split(/[:;,]/),
      type= parts[1],
      decoder= parts[2] == "base64" ? atob : decodeURIComponent,
      binData= decoder( parts.pop() ),
      mx= binData.length,
      i= 0,
      uiArr= new Uint8Array(mx);

    for(i;i<mx;++i) uiArr[i]= binData.charCodeAt(i);

    return new myBlob([uiArr], {type: type});
  }

  function saver(url, winMode){

    if ('download' in anchor) { //html5 A[download]
      anchor.href = url;
      anchor.setAttribute("download", fileName);
      anchor.className = "download-js-link";
      anchor.innerHTML = "downloading...";
      anchor.style.display = "none";
      document.body.appendChild(anchor);
      setTimeout(function() {
        anchor.click();
        document.body.removeChild(anchor);
        if(winMode===true){setTimeout(function(){ self.URL.revokeObjectURL(anchor.href);}, 250 );}
      }, 66);
      return true;
    }

    // handle non-a[download] safari as best we can:
    if(/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
      if(/^data:/.test(url))	url="data:"+url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
      if(!window.open(url)){ // popup blocked, offer direct download:
        if(confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")){ location.href=url; }
      }
      return true;
    }

    //do iframe dataURL download (old ch+FF):
    var f = document.createElement("iframe");
    document.body.appendChild(f);

    if(!winMode && /^data:/.test(url)){ // force a mime that will download:
      url="data:"+url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
    }
    f.src=url;
    setTimeout(function(){ document.body.removeChild(f); }, 333);

  }//end saver

  if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
    return navigator.msSaveBlob(blob, fileName);
  }

  if(self.URL){ // simple fast and modern way using Blob and URL:
    saver(self.URL.createObjectURL(blob), true);
  }else{
    // handle non-Blob()+non-URL browsers:
    if(typeof blob === "string" || blob.constructor===toString ){
      try{
        return saver( "data:" +  mimeType   + ";base64,"  +  self.btoa(blob)  );
      }catch(y){
        return saver( "data:" +  mimeType   + "," + encodeURIComponent(blob)  );
      }
    }

    // Blob but not URL support:
    reader=new FileReader();
    reader.onload=function(e){
      saver(this.result);
    };
    reader.readAsDataURL(blob);
  }
  return true;
}
